#include "soundmanager.hpp"

using namespace Shiny;

SoundManager* SoundManager::_instance = 0;

bool SoundManager::Play(Sound* sound)
{
  unsigned int channel = sound->GetBuffer()->GetChannelCount();

  if (channel + _usedChannels < _maxChannels)
  {
    _sounds.push_back(sound);
    sound->Play();
    return (true);
  }
  return (false);
}

void SoundManager::Run(void)
{
  Sounds::iterator it  = _sounds.begin();
  Sounds::iterator end = _sounds.end();

  while (it != end)
  {
    switch ((*it)->GetStatus())
    {
      case sf::SoundSource::Stopped:
        _usedChannels -= (*it)->GetBuffer()->GetChannelCount();
        (*it)->Ended.Emit(*it);
        it = _sounds.erase(it);
        break ;
      case sf::SoundSource::Paused:
      case sf::SoundSource::Playing:
        ++it;
        break ;
    }
  }
}

void SoundManager::StopPlaying(Sound* sound)
{
  Sounds::iterator it  = _sounds.begin();
  Sounds::iterator end = _sounds.end();

  for (; it != end ; ++it)
  {
    if (*it == sound)
    {
      (*it)->Stop();
      _usedChannels -= (*it)->GetBuffer()->GetChannelCount();
      it = _sounds.erase(it);
    }
    else
      ++it;
  }
}


/*
 * Music Manager
 */
MusicManager* MusicManager::_instance = 0;

MusicManager::MusicManager()
{
  _currentTrack = 0;
}

MusicManager::~MusicManager()
{
  Musics::iterator it  = _tracks.begin();
  Musics::iterator end = _tracks.end();

  for (; it != end ; ++it)
  {
    delete *it;
  }  
}

MusicManager* MusicManager::Get(void)
{
  return (_instance ? _instance : new MusicManager);
}

void          MusicManager::Destroy(void)
{
  if (_instance)
  {
    delete _instance;
    _instance = 0;
  }
}

void MusicManager::Load(const std::string& filename)
{
  Music* addedTrack = new MusicManager::Music();

  addedTrack->filename = filename;
  addedTrack->OpenFromFile(filename);
  _tracks.push_back(addedTrack);
}

void MusicManager::Unload(const std::string& filename)
{
  Musics::iterator it  = _tracks.begin();
  Musics::iterator end = _tracks.end();
  
  while (it != end)
  {
    if ((*it)->filename == filename)
    {
      delete *it;
      it = _tracks.erase(it);
    }
    else
      ++it;
  }
}

void MusicManager::Play(const std::string& filename)
{
  Musics::iterator it  = _tracks.begin();
  Musics::iterator end = _tracks.end();

  for (; it != end ; ++it)
  {
    if ((*it)->filename == filename)
    {
      if (_currentTrack)
        _currentTrack->Stop();
      _currentTrack = (*it);
      _currentTrack->Play();
      break ;
    }
  }
}
